package com.loan.market.view;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.RectF;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;

import androidx.annotation.NonNull;

import com.loan.market.R;
import com.loan.market.util.ScreenKt;

import java.util.Arrays;
import java.util.List;

public class SideBarView extends View {
    private OnTouchLetterChangeListener listener;
    private List<String> mLetters;
    private int mChoose = -1;

    private final Paint mLettersPaint = new Paint();

    private final Paint mTextPaint = new Paint();
    private Paint mWavePaint = new Paint();

    private float mTextSize;
    private int mTextColor;
    private int mTextColorChoose;
    private int mWidth;
    private int mHeight;
    private int mItemHeight;
    private int mPadding;

    private int mCenterY;
    private int mRadius;

    private float mPosX, mPosY;
    private float mBallCentreX;

    public SideBarView(Context context) {
        this(context, null);
    }

    public SideBarView(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public SideBarView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        init(context);
    }

    private void init(Context context) {
        mLetters = Arrays.asList("#", "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z");
        mTextColor = context.getColor(R.color.color_999);
        int circleColor = context.getColor(R.color.color_accent);
        mTextColorChoose = context.getColor(R.color.color_accent);
        mTextSize = ScreenKt.dp2px(10f);
        float mLargeTextSize = ScreenKt.dp2px(45f);
        mPadding = ScreenKt.dp2px(10f);
        mRadius = ScreenKt.dp2px(40f);

        mWavePaint = new Paint();
        mWavePaint.setAntiAlias(true);
        mWavePaint.setStyle(Paint.Style.FILL);
        mWavePaint.setColor(circleColor);

        mTextPaint.setAntiAlias(true);
        mTextPaint.setColor(Color.WHITE);
        mTextPaint.setStyle(Paint.Style.FILL);
        mTextPaint.setTextSize(mLargeTextSize);
        mTextPaint.setTextAlign(Paint.Align.CENTER);
    }

    @Override
    public boolean dispatchTouchEvent(MotionEvent event) {
        final float x = event.getX();
        final float y = event.getY();
        int oldChoose = mChoose;
        int newChoose = (int) (y / mHeight * mLetters.size());
        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                if (x < mWidth - 2.6 * mTextSize) {
                    return false;
                }
                mChoose = newChoose;
                if (listener != null) {
                    listener.onLetterChange(mLetters.get(newChoose));
                }
                invalidate();
                break;
            case MotionEvent.ACTION_MOVE:
                if (oldChoose != newChoose && newChoose >= 0 && newChoose < mLetters.size()) {
                    mChoose = newChoose;
                    if (listener != null) {
                        listener.onLetterChange(mLetters.get(newChoose));
                    }
                }
                invalidate();
                break;
            case MotionEvent.ACTION_CANCEL:
            case MotionEvent.ACTION_UP:
                mChoose = -1;
                invalidate();
                break;
            default:
                break;
        }
        return true;
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        mHeight = MeasureSpec.getSize(heightMeasureSpec);
        mWidth = getMeasuredWidth();
        mItemHeight = (mHeight - mPadding) / mLetters.size();
        mPosX = mWidth - 1.6f * mTextSize;
    }

    @Override
    protected void onDraw(@NonNull Canvas canvas) {
        super.onDraw(canvas);
        drawLetters(canvas);
        if (mChoose >= 0) {
            drawBallPath(canvas);
        }
        drawChooseText(canvas);

    }

    private void drawLetters(Canvas canvas) {

        RectF rectF = new RectF();
        rectF.left = mPosX - mTextSize;
        rectF.right = mPosX + mTextSize;
        rectF.top = mTextSize / 2;
        rectF.bottom = mHeight - mTextSize / 2;

        mLettersPaint.reset();

        for (int i = 0; i < mLetters.size(); i++) {
            mLettersPaint.reset();
            mLettersPaint.setColor(mTextColor);
            mLettersPaint.setAntiAlias(true);
            mLettersPaint.setTextSize(mTextSize);
            mLettersPaint.setTextAlign(Paint.Align.CENTER);

            Paint.FontMetrics fontMetrics = mLettersPaint.getFontMetrics();
            float baseline = Math.abs(-fontMetrics.bottom - fontMetrics.top);

            float posY = mItemHeight * i + baseline / 2 + mPadding;

            if (i == mChoose) {
                mPosY = posY;
            } else {
                canvas.drawText(mLetters.get(i), mPosX, posY, mLettersPaint);
            }
        }

    }

    private void drawChooseText(Canvas canvas) {
        if (mChoose != -1) {
            // 绘制右侧选中字符
            mLettersPaint.reset();
            mLettersPaint.setColor(mTextColorChoose);
            mLettersPaint.setTextSize(mTextSize);
            mLettersPaint.setTextAlign(Paint.Align.CENTER);
            canvas.drawText(mLetters.get(mChoose), mPosX, mPosY, mLettersPaint);

            String target = mLetters.get(mChoose);
            Paint.FontMetrics fontMetrics = mTextPaint.getFontMetrics();
            float baseline = Math.abs(-fontMetrics.bottom - fontMetrics.top);
            float x = mBallCentreX;
            float y = mCenterY + baseline / 2;
            canvas.drawText(target, x, y, mTextPaint);
        }
    }

    private void drawBallPath(Canvas canvas) {
        mBallCentreX = (float) mWidth / 2;
        mCenterY = mHeight / 2;
        canvas.drawCircle(mBallCentreX, mCenterY, mRadius, mWavePaint);
    }

    public void setOnTouchLetterChangeListener(OnTouchLetterChangeListener listener) {
        this.listener = listener;
    }

    public List<String> getLetters() {
        return mLetters;
    }

    public void setLetters(List<String> letters) {
        this.mLetters = letters;
        invalidate();
    }

    public interface OnTouchLetterChangeListener {
        void onLetterChange(String letter);
    }
}